﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TcpSyncClient
{
    public partial class Form1 : Form
    {
        private IPAddress localAddress;
        private const int port = 5656;
        private TcpClient tcpClient;
        private NetworkStream networkStream;
        private BinaryReader binaryReader;
        private BinaryWriter binaryWriter;
        // 声明委托
        private delegate void ShowMessage(string str); //显示消息
        private ShowMessage showMessage;
        private delegate void ShowStatus(string str); // 显示状态
        private ShowStatus showStatus;
        private delegate void ShowProgress(int progress); // 显示进度条
        private ShowProgress showProgress;
        private delegate void ResetText();
        private ResetText resetText;
        public Form1()
        {
            InitializeComponent();
            //定义委托
            // 显示消息委托
            showMessage = new ShowMessage(ShMsgForView);
            // 展示状态
            showStatus = new ShowStatus(ShwStatusInfo);
            // 展示进度
            showProgress = new ShowProgress(ShwProgressProc);
            //重置消息文本
            resetText = new ResetText(ResetMsgText);
        }

        /// <summary>
        /// 展示消息
        /// </summary>
        /// <param name="str"></param>
        private void ShMsgForView(string str)
        {
            // Environment.NewLine 回车换行
            str = System.DateTime.Now.ToString() + Environment.NewLine + str + Environment.NewLine;
            int txtGetMsgLength = this.richTextBox1.Text.Length;
            this.richTextBox2.AppendText(str);
            // txtGetMsgLength 开始长度
            // str.Length - Environment.NewLine.Length * 2 - str.Length 总长度
            this.richTextBox2.Select(txtGetMsgLength, str.Length - Environment.NewLine.Length * 2 - str.Length);
            this.richTextBox2.SelectionColor = Color.Red;
            // 将控件内容滚动到当前文字插入位置
            this.richTextBox2.ScrollToCaret();
        }

        /// <summary>
        /// 展示状态
        /// </summary>
        /// <param name="str"></param>
        private void ShwStatusInfo(string str)
        {
            toolStripStatusLabel1.Text = str;
        }

        /// <summary>
        /// 显示进度
        /// </summary>
        /// <param name="proc"></param>
        private void ShwProgressProc(int proc)
        {
            toolStripProgressBar1.Value = proc;
        }

        /// <summary>
        /// 重置消息文本
        /// </summary>
        private void ResetMsgText()
        {
            richTextBox1.Text = "";
            richTextBox1.Focus();
        }

        /// <summary>
        /// 发起连接请求
        /// </summary>
        private void ConnectToServer()
        {
            try
            {
                statusStrip1.Invoke(showStatus, "正在连接...");
                // 创建远程服务地址ip
                IPHostEntry remoteHost = Dns.GetHostEntry(textBox1.Text);
                // 创建tcp客户端连接
                tcpClient = new TcpClient();
                statusStrip1.Invoke(showProgress, 1);
                // tcp连接服务端地址
                tcpClient.Connect(remoteHost.HostName, 5656);
                statusStrip1.Invoke(showProgress, 100);
                DateTime now = DateTime.Now;
                while (now.AddSeconds(1) > DateTime.Now) { }
                // 如果tcpclient 不等于null 说明连接成功
                if (tcpClient != null)
                {
                    statusStrip1.Invoke(showStatus, "连接成功");
                    // 连接成功之后准备收发数据
                    // 实例化网络流对象
                    networkStream = tcpClient.GetStream();
                    // 实例化二进制读取数据对象
                    binaryReader = new BinaryReader(networkStream);
                    // 实例化二进制写数据对象
                    binaryWriter = new BinaryWriter(networkStream);
                }
            }
            catch (Exception e)
            {
                statusStrip1.Invoke(showStatus, "连接失败");
                DateTime now = DateTime.Now;
                while (now.AddSeconds(1) < DateTime.Now)
                { }
                statusStrip1.Invoke(showProgress, 0);
                statusStrip1.Invoke(showStatus, "就绪");
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        private void ReceiveMessage()
        {
            statusStrip1.Invoke(showStatus, "接收中...");
            // 发送五条消息
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    // 二进制读取字符串
                    string rcvMsgStr = binaryReader.ReadString();
                    // 更改进度条
                    statusStrip1.Invoke(showProgress, i + 1);
                    // 接受到的数据显示文本框中
                    if (rcvMsgStr != null)
                    {
                        //
                        richTextBox2.Invoke(showMessage, rcvMsgStr);
                    }
                }
                catch (Exception e)
                {
                    // 关闭所有资源
                    if (binaryReader != null)
                    {
                        binaryReader.Close();
                    }
                    if (binaryWriter != null)
                    {
                        binaryWriter.Close();
                    }
                    if (tcpClient != null)
                    {
                        tcpClient.Close();
                    }
                    statusStrip1.Invoke(showStatus, "连接断开!");
                    statusStrip1.Invoke(showProgress, 0);
                    break;
                }
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="state"></param>
        private void SendMessage(object state)
        {
            statusStrip1.Invoke(showStatus, "正在发送消息");
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    // 二进制写入字符串数据
                    binaryWriter.Write(state.ToString());
                    statusStrip1.Invoke(showProgress, i + 1);
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(5) > dateTime) { }
                    binaryWriter.Flush();
                }
                catch
                {
                    if (binaryReader != null)
                    {
                        binaryReader.Close();
                    }
                    if (binaryWriter != null)
                    {
                        binaryWriter.Close();
                    }
                    if (tcpClient != null)
                    {
                        tcpClient.Close();
                    }
                    statusStrip1.Invoke(showStatus, "连接断开");
                    statusStrip1.Invoke(showProgress, 0);
                    break;
                }
            }
            statusStrip1.Invoke(showStatus, "完毕");
            DateTime dateTime1 = DateTime.Now;
            while (dateTime1.AddSeconds(1) > dateTime1) { }
            statusStrip1.Invoke(showProgress, 0);
            textBox1.Invoke(resetText, null);
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(new ParameterizedThreadStart(SendMessage));
            thread.Start(textBox1.Text);
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(ReceiveMessage);
            thread.Start();
        }

        /// <summary>
        /// 连接服务端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(ConnectToServer);
            thread.Start();
        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {
            Task.Run(() =>
            {

            });
        }
    }
}
